﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.SqlServer.Management.Common;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.ComponentModel;
using System.Windows.Media.Animation;

namespace WPFLogin
{
    /// <summary>
    /// Interaction logic for winLogin.xaml
    /// </summary>
    public partial class Login : Window
    {
        #region | Declarations |

        private BackgroundWorker loadingTimer;

        #region | Move Window |

        public const int WM_NCLBUTTONDOWN = 0xA1;
        public const int HT_CAPTION = 0x2;

        [DllImportAttribute("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

        [DllImportAttribute("user32.dll")]
        public static extern bool ReleaseCapture();

        #endregion

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="winLogin"/> class.
        /// </summary>
        public Login()
        {
            InitializeComponent();
        }

        #region |- Events -|

        /// <summary>
        /// Handles the Loaded event of the Window control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.txtVersion.Text = "v. " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
        }

        /// <summary>
        /// Handles the Click event of the btnAceptar control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            // Validation
            this.ShowMessage(Visibility.Hidden, "");
            if (string.IsNullOrEmpty(this.txtUser.Text.Trim()))
            {
                this.ShowMessage(Visibility.Visible, "Username is requiered.");
                this.txtUser.Focus();
                return;
            }

            if (string.IsNullOrEmpty(this.txtPassword.Password.Trim()))
            {
                this.ShowMessage(Visibility.Visible, "Password is requiered.");
                this.txtPassword.Focus();
                return;
            }

            try
            {
                // Hide the textbox, show and begin the animation
                this.grdMainControls.Visibility = Visibility.Hidden;
                this.grdLoading.Visibility = Visibility.Visible;

                Storyboard strLoading = (Storyboard)this.FindResource("LoadingAnimation");
                strLoading.Begin();

                // Thread
                this.loadingTimer = new BackgroundWorker();
                this.loadingTimer.WorkerReportsProgress = true;
                this.loadingTimer.WorkerSupportsCancellation = true;

                // Events
                this.loadingTimer.DoWork += new DoWorkEventHandler(loadingTimer_DoWork);
                this.loadingTimer.RunWorkerCompleted += new RunWorkerCompletedEventHandler(loadingTimer_RunWorkerCompleted);

                // Parameters
                Dictionary<string, string> Parm = new Dictionary<string, string>();
                Parm.Add("User", this.txtUser.Text);
                Parm.Add("Password", this.txtPassword.Password);

                this.loadingTimer.RunWorkerAsync(Parm);
            }
            catch (Exception)
            {
                this.grdMainControls.Visibility = Visibility.Visible;
                this.grdLoading.Visibility = Visibility.Hidden;
                this.ShowMessage(Visibility.Visible, "An Error as ocurred.");
            }
        }

        #region |- Thread Events -|

        /// <summary>
        /// Handles the DoWork event of the loadingTimer control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.DoWorkEventArgs"/> instance containing the event data.</param>
        private void loadingTimer_DoWork(object sender, DoWorkEventArgs e)
        {
            Dictionary<string, string> P = (Dictionary<string, string>)e.Argument;

            // Temporary sleep so you can see the animation.
            System.Threading.Thread.Sleep(5000);

            // Validar las credenciales
            if (this.ValidateCredentials(P["User"].ToString(), P["Password"].ToString()))
                e.Result = true;
            else
                e.Result = false;
        }

        /// <summary>
        /// Handles the RunWorkerCompleted event of the loadingTimer control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.RunWorkerCompletedEventArgs"/> instance containing the event data.</param>
        private void loadingTimer_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                // Stop the animation
                Storyboard strLoading = (Storyboard)FindResource("LoadingAnimation");
                strLoading.Stop();

                if ((bool)e.Result) // Success
                {
                    this.ShowMessage(Visibility.Visible, "Login Successfully");
                    MainWindow win = new MainWindow();
                    win.Show();
                    this.Close();
                }
                else
                {
                    this.grdLoading.Visibility = Visibility.Hidden;
                    this.grdMainControls.Visibility = Visibility.Visible;
                }
            }
            catch (Exception)
            {
            }
        }

        #endregion

        /// <summary>
        /// Handles the Click event of the btnCancelar control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// Handles the GotFocus event of the IdUsuario control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void txtUser_GotFocus(object sender, RoutedEventArgs e)
        {
            // Hide the label lblUsr
            txtUser.ClipToBounds = true;
        }

        /// <summary>
        /// Handles the LostFocus event of the IdUsuario control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void txtUser_LostFocus(object sender, RoutedEventArgs e)
        {
            // Show the label lblUsr
            if (string.IsNullOrEmpty(txtUser.Text))
            {
                txtUser.ClipToBounds = false;
            }
        }

        /// <summary>
        /// Handles the GotFocus event of the Password control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void txtPassword_GotFocus(object sender, RoutedEventArgs e)
        {
            // Hide the label lblPwd
            txtPassword.ClipToBounds = true;
        }

        /// <summary>
        /// Handles the LostFocus event of the Password control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void txtPassword_LostFocus(object sender, RoutedEventArgs e)
        {
            // Show the label lblPwd
            if (string.IsNullOrEmpty(txtPassword.Password))
            {
                txtPassword.ClipToBounds = false;
            }
        }

        /// <summary>
        /// Handles the TextChanged event of the IdUsuario control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Controls.TextChangedEventArgs"/> instance containing the event data.</param>
        private void txtUser_TextChanged(object sender, TextChangedEventArgs e)
        {
            ShowMessage(Visibility.Hidden, "");
        }

        /// <summary>
        /// Handles the PasswordChanged event of the Password control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void txtPassword_PasswordChanged(object sender, RoutedEventArgs e)
        {
            ShowMessage(Visibility.Hidden, "");
        }

        /// <summary>
        /// Handles the MouseDown event of the Window control.
        /// Moves the form.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                ReleaseCapture();
                // Move the window.
                SendMessage((new WindowInteropHelper(this)).Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
            }
        }

        /// <summary>
        /// Handles the PreviewKeyDown event of the txtUser control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.KeyEventArgs"/> instance containing the event data.</param>
        private void txtUser_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                this.btnLogin.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
                this.txtUser.Focus();
                e.Handled = true;
            }
        }

        /// <summary>
        /// Handles the PreviewKeyDown event of the txtPassword control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.KeyEventArgs"/> instance containing the event data.</param>
        private void txtPassword_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                this.btnLogin.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
                this.txtPassword.Focus();
                e.Handled = true;
            }
        }

        #endregion

        #region Functions

        /// <summary>
        /// Shows the message.
        /// </summary>
        /// <param name="Show">if set to <c>true</c> [show].</param>
        /// <param name="Message">The message.</param>
        private void ShowMessage(Visibility Show, string Message)
        {
            this.txtMsg.Text = Message;
            this.txtMsg.Visibility = Show;
        }

        /// <summary>
        /// Validates the credentials against SQL Server.
        /// </summary>
        /// <returns>True if the credentials are valid</returns>
        private bool ValidateCredentials(string strUser, string strPassword)
        {
            #region |- SQL Server -|

            //try
            //{
            //    ServerConnection myServerConn = new ServerConnection();

            //    myServerConn.LoginSecure = true;
            //    myServerConn.ConnectAsUser = true;

            //    // I asume that your current machine is the name of the server.
            //    myServerConn.ServerInstance = Environment.MachineName.ToString();

            //    myServerConn.ConnectAsUserName = txtUser.Text.Trim();
            //    myServerConn.ConnectAsUserPassword = txtPassword.Password.Trim();

            //    myServerConn.Connect();
            //    return true;
            //}
            //catch (Exception ex)
            //{
            //    ShowMessage(Visibility.Visible, "Logon failure: unknown user name or bad password.");
            //    Console.WriteLine(ex.Message);
            //    return false;
            //}

            #endregion

            #region |- Static Login -|

            if (strUser.Trim() == "user" && strPassword.Trim() == "password")
                return true;
            else
            {
                Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, (System.Threading.SendOrPostCallback)delegate
                {
                    ShowMessage(Visibility.Visible, "Logon failure: unknown user name or bad password.");
                }, null);

                return false;
            }

            #endregion
        }

        #endregion
    }
}
